package configcenter;

import cn.edu.hit.CacheManager;
import cn.edu.hit.core.db.DBReadHelper;
import cn.edu.hit.core.db.DataConnection;
import cn.edu.hit.core.db.DataConnectionLoader;
import cn.edu.hit.core.db.DataReader;
import cn.edu.hit.kg.data.GraphData;
import cn.edu.hit.kg.data.Node;
import cn.edu.hit.selflearning.RedisController;
import net.sf.json.JSONObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import java.io.*;
import java.util.ArrayList;
import java.util.stream.Collectors;
import java.util.stream.StreamSupport;

@RestController
public class StartController {
    static Logger logger = LoggerFactory.getLogger(RedisController.class);
    static DataConnection connection = DataConnectionLoader.getInstance();
    static DataReader reader = connection.getReader();
    static DBReadHelper dbHelper = new DBReadHelper(reader);
    static GraphData graphData = GraphData.getInstance();
    public static final CacheManager cacheManager = CacheManager.getInstance();

    @Autowired
    HttpServletRequest request;

    @CrossOrigin
    @RequestMapping(method = RequestMethod.POST, value = "query2", produces = "application/json;charset=UTF-8", consumes = "application/json")
    public String savetofile() throws IOException {

        BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(request.getInputStream(), "UTF-8"));
        String path = "./data.json";
        File file = new File(path);
        FileOutputStream fileOutputStream = new FileOutputStream(file);
        String line = null;
        while ((line = bufferedReader.readLine()) != null) {
            fileOutputStream.write(line.getBytes());
        }
        fileOutputStream.close();

        return "推理完成";
    }

    public JSONObject loadFeature(String machineNumber, long id, long faultId) {
        String freqKey = "feature_frequency:" + machineNumber + ':' + id;
        JSONObject freq;

        if (cacheManager.getJedis().exists(freqKey)) {
            freq = JSONObject.fromObject(cacheManager.getJedis().get(freqKey));
        } else {
            GraphData graphData = GraphData.getInstance();
            freq = new JSONObject();
            Node feature = graphData.getById(id);
            if (feature.asMap().get("quantum") == null) {
                freq.put("quantum", 100);
            } else {
                freq.put("quantum", feature.asMap().get("quantum"));
            }
            if (feature.asMap().get("frequency") == null) {
                JSONObject fault = new JSONObject();
                fault.put("" + faultId, 10);
                freq.put("frequency", fault);
            } else {
                JSONObject fault = new JSONObject();
                fault.put("" + faultId, feature.asMap().get("frequency"));
                freq.put("frequency", fault);
            }
        }
//        jedis.close();
        return freq;
    }

    public JSONObject loadReasonFreq(@PathVariable("machineNumber") String machineNumber, @PathVariable("id") long fault_id) {
        String freqKey = "fault_reason:" + machineNumber + ":" + fault_id;
        JSONObject freq;
        if (cacheManager.getJedis().exists(freqKey)) {
            freq = JSONObject.fromObject(cacheManager.getJedis().get(freqKey));
        } else {
            freq = new JSONObject();
            Node fault = graphData.getById(fault_id);
            freq.put("quantum", fault.asMap().getOrDefault("quantum", 100));
            if (fault.asMap().containsKey("frequency")) {
                freq.put("frequency", fault.asMap().get("frequency"));
            } else {
                freq.put("frequency", graphData.getAllSubNodes(fault_id)
                        .filter(node -> StreamSupport.stream(node.labels().spliterator(), false)
                                .anyMatch(x -> x.equals("Reason")))
                        .collect(Collectors.toMap(x -> "" + x.id(), x -> Double.parseDouble(x.asMap().get("probability").toString()) * 100)));
            }
        }
        return freq;
    }

    @CrossOrigin
    @RequestMapping(method = RequestMethod.GET, value = "train2/{machineNumber}/{id}", produces = "application/json;charset=UTF-8")
    public JSONObject train(@PathVariable("machineNumber") String machineNumber, @PathVariable("id") String reportId, @RequestParam("features") String fs, @RequestParam("reasons") String reasons) {
        fs = fs.substring(1, fs.length() - 1);
        String[] strArray = fs.split(",");
        ArrayList list = new ArrayList();
        for (int i = 0; i < strArray.length; i++) {
            list.add(strArray[i]);
        }

        String line = cacheManager.getJedis().lpop("fault_feature:" + machineNumber + ":" + reportId);
        JSONObject faultJson = JSONObject.fromObject(line);
        long faultId = faultJson.getLong("fault_id");

        for (int i = 0; i < list.size(); i++) {
            long featureId = Long.parseLong(list.get(i).toString());
            JSONObject Featurefreq = loadFeature(machineNumber, featureId, faultId);
            Featurefreq.put("quantum", Featurefreq.optInt("quantum") + 1);
            Featurefreq.getJSONObject("frequency").put("" + faultId, Featurefreq.getJSONObject("frequency").optInt("" + faultId) + 1);
            String freqKey = "feature_frequency:" + machineNumber + ":" + featureId;
            String res = Featurefreq.toString();
            cacheManager.getJedis().set(freqKey, res);
        }

        reasons = reasons.substring(1, reasons.length() - 1);
        String[] strArray2 = reasons.split(",");
        ArrayList list2 = new ArrayList();
        for (int i = 0; i < strArray2.length; i++) {
            list2.add(strArray2[i]);
        }

        JSONObject reasonFreq = loadReasonFreq(machineNumber, faultId);
        for (int i = 0; i < list2.size(); i++) {
            long reason = Long.parseLong(list2.get(i).toString());
            reasonFreq.put("quantum", reasonFreq.optInt("quantum") + 1);
            reasonFreq.getJSONObject("frequency").put("" + reason, reasonFreq.getJSONObject("frequency").optInt("" + reason) + 1);
        }

        cacheManager.getJedis().set("fault_reason:" + machineNumber + ":" + faultId, reasonFreq.toString());

        cacheManager.getJedis().del("fault_feature:" + machineNumber + ":" + reportId);
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("result", true);
//        jedis.close();
        logger.info("已训练reportId:{}", reportId);
        return jsonObject;
    }

    @CrossOrigin
    @RequestMapping(method = RequestMethod.GET, value = "clear2/{machineNumber}/{id}", produces = "application/json;charset=UTF-8")
    public JSONObject clear(@PathVariable("machineNumber") String machineNumber, @PathVariable("id") String reportId) {
        cacheManager.getJedis().del("fault_feature:" + machineNumber + ":" + reportId);
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("result", true);
        logger.info("已删除reportId：{}", reportId);
        return jsonObject;
    }
}
